import deepMerge from 'deepmerge';
import md5 from 'js-md5';
import conf from '@/config';
import urls from './url-type';
import axios from 'axios';

const http = axios.create();

const defaultConf = {
  method: 'post',
  headers: { 'Content-Type': 'application/json' },
  data: {},
  transformRequest: [(params,headers) => {
    if(`application/json` === headers[`Content-Type`]){
      const jsonData = Object.assign(defaultParams, {
        sign: getSign(defaultParams),
        userId: 'userId',
        data:params,
        token: 'token'
      });
      return JSON.stringify(jsonData);
    }

  }],
};


/**
 * 请求默认参数
 *
 */
const defaultParams = {
    sign:'',
    from: 'pc',
    version: 0,
    timestamp: new Date().getTime(),
    userId:'',
    token:''
};


/**
 * 签名方法
 * @param {[Object]} params
 */
function getSign(params) {
  const pArr = Object.keys(params).sort();
  const noSignArr = ['from', 'version', 'timestamp', 'userid', 'sign','data'];
  const signStr = pArr.map(key => (
      params[key] && noSignArr.indexOf(key) < 0
        ? `${key}${params[key]}`
        : ''
    ))
    .join('');

  const sign = md5(`B@t0nsccF2qZe$xR${signStr}`);

  return sign.toLocaleUpperCase();
}

/**
 * 填充 baseUrl
 *
 * @param {any} url
 * @param {any} baseUrl
 * @returns
 */
function fillBaseUrl(url, baseUrl) {
  if (url.indexOf('//') > -1) {
    return url;
  }
  baseUrl = baseUrl || conf.api.baseUrl;
  return `${baseUrl}${url}`;
}

/**
 * 组装http请求
 * @param  {[type]} urlVal [description]
 * @return {[type]}        [description]
 */
function assembleHttp(urlVal) {
  if (typeof urlVal === 'string') {
    urlVal = {
      url: urlVal,
      method: 'post',
    };
  }

  urlVal.url = fillBaseUrl(urlVal.url, urlVal.baseUrl);

  return (params = {}, config = {}) => {
    config = deepMerge.all([{}, defaultConf, urlVal, config || {}], {
      clone: true,
    });

    if (['post', 'put', 'patch'].indexOf(config.method) > -1) {
      config.data = Object.assign(config.data, params);
    } else {
      config.params = Object.assign(config.params || {}, params);
    }

    return http(config).then(response => response.data);
  };
}

/**
 * 填充方法
 * @param  {[type]} apiObj [description]
 * @param  {[type]} urls   [description]
 * @return {[type]}        [description]
 */
function fillMethods(apiObj, urlObj) {
  const urlKeys = Object.keys(urlObj);

  urlKeys.forEach((urlKey) => {
    const urlVal = urlObj[urlKey];

    if (typeof urlVal === 'string') {
      apiObj[urlKey] = assembleHttp(urlVal);
    } else if (urlVal.url) {
      apiObj[urlKey] = assembleHttp(urlVal);
    } else {
      apiObj[urlKey] = {};
      fillMethods(apiObj[urlKey], urlVal);
    }
  });
}

/**
 * Api 类
 */
class Api {
  /**
   * 作为Vue插件进行安装，挂载到Vue.prototype
   */
  install(Vue) {
    Vue.prototype.$api = this;
  }
}

fillMethods(Api.prototype, urls);

export default new Api(http);
